package token

import (
	"coolcar/v1/shared/ids"
	"crypto/rsa"
	"github.com/dgrijalva/jwt-go"
)

// JWTTokenVerifier verifies jwt token access tokens.
type JWTTokenVerifier struct {
	PublicKey *rsa.PublicKey
}

// NewJWTTokenVerifier verifies jwt token.
func NewJWTTokenVerifier(publicKey *rsa.PublicKey) *JWTTokenVerifier {
	return &JWTTokenVerifier{
		PublicKey: publicKey,
	}
}

// Verify verifies jwt token and returns account id.
func (v *JWTTokenVerifier) Verify(token string) (ids.AccountID, error) {
	tkn, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
		return v.PublicKey, nil
	})
	if err != nil {
		return "", err
	}
	if !tkn.Valid {
		return "", err
	}
	clm, ok := tkn.Claims.(*jwt.StandardClaims)
	if !ok {
		return "", err
	}
	if err = clm.Valid(); err != nil {
		return "", err
	}
	return ids.AccountID(clm.Subject), nil
}
